/* eslint-disable react/jsx-no-bind */
/* eslint-disable react/jsx-indent-props */
import React, { useCallback } from 'react';
import {
    Form,
    Checkbox,
    Row,
    Col,
    Select,
    Alert,
    Input,
    Upload,
    message,
} from 'antd';
import axios from 'axios';
import _ from 'lodash';
import ImgCrop from 'antd-img-crop';
import 'antd/dist/antd.css';
import { getSession, getCellValueForSpecial, isCellChoiceForSpecial } from '../common/help';

import { ContentConfigProps, RowItemConfigProps } from '../props-type';
import '../style/index.less';

const FormItem = Form.Item;
const { Option } = Select;
const { TextArea } = Input;

/**
 * 组件功能：内容配置区块页面
 *
 */
const ContentConfig = ({
    type,
    brandList,
    // fileListLogo,
    billImageList,
    // fileListBottomPic,
    templateJson,
    billJson,
    brandId,
    billName,
    form: {
        getFieldDecorator,
        getFieldValue,
    },
    onUpdateStateSuper,
    onChooseBillJson,
    onUploadImg,
    onChangeCellValue,
}: ContentConfigProps) => {
    const formItemLayout = {
        labelCol: { span: 6 },
        wrapperCol: { span: 18 },
    };
    // 需要计算出当前billJson里存在的cell_id的数组，也需要过滤掉空行跟分割符行的情况
    const selectedCellId = [];
    const selectedRowId = []; // 主要用作父级row没选的情况下，子row_child下的节点不可选的判断
    // 动态计算出logo跟图片的数组值
    const fileListLogo = [];
    const logoId = getCellValueForSpecial('logo', billJson);
    billImageList.forEach(item => {
        if (item.imageId === logoId) {
            fileListLogo.push(
                {
                    uid: item.imageId,
                    url: item.imageUrl,
                }
            );
        }
    });
    // 动态计算底部图片的数组信息
    const fileListBottomPic = [];
    const imageId = getCellValueForSpecial('bottomPic', billJson);
    billImageList.forEach(item => {
        if (item.imageId === imageId) {
            fileListBottomPic.push(
                {
                    uid: item.imageId,
                    url: item.imageUrl,
                }
            );
        }
    });
    // 定义图片格式
    const imageType = ['jpeg', 'jpg', 'bmp', 'png', 'gif'];
    // handleChangeImage
    const handleChangeImage = useCallback(({ file }) => {
        // 这里考虑图片删除的情况
        // 删除图片,考虑更新定级组件的billImageList
        if (file.status === 'removed') {
            // 调用接口删除图片
            // 抛出新的promise对象
            axios.get(`/choice-saas-base/paper/deleteImage?imageId=${file.uid}`, {
                headers: {
                    Accept: '*/*',
                    Authorization: `Bearer ${getSession('accessToken')}`,
                },
            }).then((resData) => {
                const cacheBillImageList = billImageList.filter(item => item.imageId !== file.uid);
                onUpdateStateSuper({ billImageList: cacheBillImageList });
            }).catch((err) => {
                console.log('删除图片', err);
            });
        }
    }, [billImageList, onUpdateStateSuper]);
    // handleBeforeCrop
    const handleBeforeCrop = useCallback((file) => {
        // 图片格式判断
        if (imageType.indexOf(file.type.split('/')[1].toLowerCase()) === -1) {
            message.warn('请上传jpeg,jpg.bmp,png,gif格式文件');
            return false;
        } else {
            return true;
        }
    }, [imageType]);
    // logo预览
    const handlePreviewImage = async (file) => {
        let src = file.url;
        if (!src) {
            src = await new Promise((resolve) => {
                const reader = new FileReader();
                reader.readAsDataURL(file.originFileObj);
                reader.onload = () => resolve(reader.result);
            });
        }
        const image = new Image();
        image.src = src;
        const imgWindow = window.open(src);
        imgWindow.document.write(image.outerHTML);
    };
    // logo自定义上传
    const customRequest = (option): any => {
        const {
            action,
            file,
            data,
            headers,
            onError,
            onProgress,
            onSuccess,
        } = option;
        // 图片大小判断，这里在裁剪后上传前判断，目的是裁剪后图片尺寸会变化
        if (file.size > 1 * 1024 * 1024) {
            message.warn('请上传1M以内的图片');
            return false;
        }
        // 组装参数
        const formData = new FormData();
        //   formData.append(filename, file);
        //   file.originalFilename = file.name;
        formData.append('imageFile', file);
        formData.append('imageName', file.name);
        // 抛出新的promise对象
        axios.post(action, formData, {
            headers,
            onUploadProgress: ({ total, loaded }) => {
                onProgress({ percent: Math.round((loaded / total) * 100).toFixed(2) }, file);
            },
        }).then((resData) => {
            // 这里对返回的数据进行处理，这里需要传入返回的logo
            onUploadImg(data.imageType, resData.data.data);
            onSuccess(resData);
        }).catch(onError);
        return {
            abort() {
                console.log('upload progress is aborted.');
            },
        };
    };
    // handleChooseBillJson,选择具体cell后的方法调用
    const handleChooseBillJson = useCallback((e, itemBlock, row_id, cell_id, blockIdList, rowIdList, cellIdList, parentRowIds) => {
        // 选择与否
        const action = e.target.checked;
        // 调用容器组件具体方法
        onChooseBillJson(action, itemBlock, row_id, cell_id, blockIdList, rowIdList, cellIdList, parentRowIds);
    }, [onChooseBillJson]);
    // 选择品牌
    const handleBrandIdSelect = useCallback((value) => {
        onUpdateStateSuper({ brandId: getFieldValue('brandId') });
    }, [onUpdateStateSuper, getFieldValue]);
    // 填写票据名称
    const handleBillName = useCallback((e) => {
        onUpdateStateSuper({ billName: getFieldValue('billName') });
    }, [onUpdateStateSuper, getFieldValue]);
    // 品牌选项
    const brandOptions = brandList.map((item: any, index: number) => (
        // @ts-ignore
        <Option value={item.id} key={index}>
            {item.name}
        </Option>
    ));
    // 自定义标题
    const handleSubTitle = useCallback((e) => {
        onChangeCellValue('subTitle', getFieldValue('subTitle'));
    }, [onChangeCellValue, getFieldValue]);
    // 底部栏文字
    const handleBottomTitle = useCallback((e) => {
        onChangeCellValue('bottomTitle', getFieldValue('bottomTitle'));
    }, [onChangeCellValue, getFieldValue]);
    // 递归渲染row
    const getRows = (block_id, rows, itemBlock, blockIdList, rowIdList, childNum, parentRowIds) => {
        const rowKey = rows.length > 0 ? rows[0].row_id : '';
        return (
            <Row key={rowKey}>
                {rows.map((itemRows) => {
                    // rowItemProps
                    const rowItemProps = {
                        block_id,
                        itemRows,
                        itemBlock,
                        blockIdList,
                        rowIdList,
                        childNum,
                        parentRowIds,
                    };
                    return <RowItem key={itemRows.row_id} {...rowItemProps} />;
                })}
            </Row>
        );
    };
    // RowItem
    const RowItem = ({
        block_id,
        itemRows,
        itemBlock,
        blockIdList,
        rowIdList,
        childNum,
        parentRowIds,
    }: RowItemConfigProps): any => {
        const { cell, row_id, row_type, row_child } = itemRows;
        const rowDomRender = [];
        let rowDom = null;
        // 如果childNum为0，那么加入到rowIdList里，否则不需要增加到数组，row_child下面的rowIdList动态计算，这里由于递归无法给出有效的值
        if (childNum < 1 && rowIdList.indexOf(row_id) < 0) {
            rowIdList.push(row_id);
        }
        // 如果分割符，那么过滤
        if (row_type === '5') return null;
        // 定义该row下面cellIdList
        const cellIdList = [];
        // 深拷贝，防止丢失，根据childNum截取当前parent
        const cacheParentRowIds = _.cloneDeep(parentRowIds);
        cacheParentRowIds.splice(childNum, cacheParentRowIds.length);
        // 另外，增加判断，如果父级没做选择，子节点不可选择; 这里需要传入具体的值，计算出父级节点是否选中，之前有选中的数组selectedCellId
        let isParentRowSelected = true;
        if (childNum > 0) {
            const parentId = parentRowIds[childNum - 1];
            isParentRowSelected = selectedRowId.indexOf(parentId) > -1;
        }
        // 渲染具体的cell项
        rowDom = (
            cell.map((itemCell) => {
                const { name, title, data_value, cell_id } = itemCell;
                cellIdList.push(cell_id);
                // 过滤空行跟分割线
                if (!title && !data_value) {
                    return null;
                }
                let cellDom;
                if (childNum < 1) {
                    cellDom = <Col key={cell_id} span={6}><Checkbox value={cell_id} onChange={e => handleChooseBillJson(e, itemBlock, row_id, cell_id, blockIdList, rowIdList, cellIdList, cacheParentRowIds)}>{name}</Checkbox></Col>;
                } else if (childNum > 0) {
                    // 如果childNumber大于0，具体row_child下面的rowIdlist因为递归原因不能传入有效的值，所以为空，具体在增加的时候动态计算出来
                    cellDom = <Col key={cell_id} span={6}><Checkbox value={cell_id} disabled={!isParentRowSelected} onChange={e => handleChooseBillJson(e, itemBlock, row_id, cell_id, blockIdList, [], cellIdList, cacheParentRowIds)}>{name}</Checkbox></Col>;
                }
                return cellDom;
            })
        );
        rowDomRender.push(rowDom);
        // 如果还存在row_child，那么继续取值
        if (row_child && Array.isArray(row_child) && row_child.length > 0) {
            // 这里需要对parentRowIds进行处理，数组当前的索引值就对应父应用的值就可以，不用push，这样更靠谱
            parentRowIds[childNum] = row_id;
            const rowChildDom = getRows(block_id, row_child, itemBlock, blockIdList, rowIdList, childNum += 1, parentRowIds);
            rowDomRender.push(rowChildDom);
        }
        // cell列表结束
        return rowDomRender;
    };
    // 递归计算选择的cellid
    const getSelectedCellId = (rows) => {
        rows.forEach((itemRows) => {
            const { cell, row_child } = itemRows;
            // 渲染具体的cell项
            cell.forEach((itemCell) => {
                const { title, data_value, cell_id } = itemCell;
                // 过滤空行跟分割线
                if (title || data_value) {
                    // 考虑不能重复加入
                    if (selectedCellId.indexOf(cell_id) < 0) {
                        selectedCellId.push(cell_id);
                    }
                    // selectedRowId计算的时候要考虑去重
                    if (selectedRowId.indexOf(itemRows.row_id) < 0) {
                        selectedRowId.push(itemRows.row_id);
                    }
                }
                // 如果存在row_child的情况，那么需要递归加入选择的值
                if (row_child && Array.isArray(selectedCellId) && row_child.length > 0) {
                    getSelectedCellId(row_child);
                }
            });
        });
    };
    // 定义block_id的数组
    const blockIdList = [];
    // 定义父级id
    // const parentIds = [];
    return (
        <div className="content-config">
            <Form {...formItemLayout}>
                <FormItem label="选择品牌" key="brandId">
                    {getFieldDecorator('brandId', {
                        initialValue: brandId || '',
                        rules: [
                            {
                                required: true,
                                message: '请选择品牌',
                            },
                        ],
                    })(<Select
                        showArrow
                        showSearch
                        disabled={type === 'edit'}
                        allowClear={false}
                        placeholder="请选择品牌"
                        onSelect={(value) => handleBrandIdSelect(value)}
                    >
                        {brandOptions}
                    </Select>)}
                </FormItem>
                <FormItem label="票据名称" key="billName">
                    {getFieldDecorator('billName', {
                        initialValue: billName || '',
                        rules: [
                            {
                                required: true,
                                message: '请输入票据名称',
                            },
                        ],
                    })(<Input onBlur={handleBillName} allowClear placeholder="限30个字符" maxLength={30} />)}
                </FormItem>
                {isCellChoiceForSpecial('logo', billJson) && <FormItem
                    label="上传logo"
                    key="logo"
                >
                    {getFieldDecorator('logo', {
                        initialValue: '',
                    })(<ImgCrop grid beforeCrop={handleBeforeCrop}>
                        <Upload
                            action="/choice-saas-base/paper/uploadImage"
                            listType="picture-card"
                            data={{
                                imageType: 'logo',
                            }}
                            fileList={fileListLogo}
                            onChange={handleChangeImage}
                            onPreview={handlePreviewImage}
                            customRequest={customRequest}
                            headers={{
                                Accept: '*/*',
                                Authorization: `Bearer ${getSession('accessToken')}`,
                            }}
                        >
                            {fileListLogo.length < 1 && '+ Upload'}
                        </Upload>
                    </ImgCrop>)}
                    <Alert message="图片上传尺寸150*150，否则图片无法正常打印！" banner />
                </FormItem>}
                {isCellChoiceForSpecial('subTitle', billJson) && <FormItem
                    label="自定义标题"
                    key="subTitle"
                >
                    {getFieldDecorator('subTitle', {
                        initialValue: getCellValueForSpecial('subTitle', billJson) || '',
                    })(<TextArea allowClear placeholder="限500个字符" maxLength={500} rows={3} onBlur={handleSubTitle} />)}
                </FormItem>}
                {/* 这里需要做必要的判断，防止后端数据错误 */}
                {templateJson && templateJson.block && Array.isArray(templateJson.block) ? templateJson.block.map((itemBlock, indexBlock) => {
                    const { name, rows, block_id } = itemBlock;
                    blockIdList.push(block_id);
                    // 定义该block下面的rowIdList
                    const rowIdList = [];
                    billJson && billJson.block && Array.isArray(billJson.block) && billJson.block.forEach((itemBlockTemplate) => {
                        // 如果billJson当前的block_id跟上面的一样，那么进行下面的选择
                        if (itemBlockTemplate.block_id === block_id) {
                            const rowsTemplate = itemBlockTemplate.rows;
                            rowsTemplate.forEach((itemRows) => {
                                const { cell, row_child } = itemRows;
                                // 渲染具体的cell项
                                cell.forEach((itemCell) => {
                                    const { title, data_value, cell_id } = itemCell;
                                    // 过滤空行跟分割线
                                    if (title || data_value) {
                                        // 考虑不能重复加入
                                        if (selectedCellId.indexOf(cell_id) < 0) {
                                            selectedCellId.push(cell_id);
                                        }
                                        // selectedRowId计算的时候要考虑去重
                                        if (selectedRowId.indexOf(itemRows.row_id) < 0) {
                                            selectedRowId.push(itemRows.row_id);
                                        }
                                    }
                                });
                                // 如果存在row_child的情况，那么需要递归加入选择的值
                                if (row_child && Array.isArray(row_child) && row_child.length > 0) {
                                    getSelectedCellId(row_child);
                                }
                            });
                        }
                    });
                    return (
                        // block开始
                        <div className="block" key={block_id}>
                            <FormItem label={name}>
                                {getFieldDecorator(`checkbox-group${block_id}`, {
                                    initialValue: selectedCellId,
                                })(
                                    <Checkbox.Group style={{ width: '100%' }}>
                                        {/* 递归具体rows */}
                                        {getRows(block_id, rows, itemBlock, blockIdList, rowIdList, 0, [])}
                                    </Checkbox.Group>,
                                )}
                            </FormItem>
                        </div>
                        // block结束
                    );
                }) : ''
                }
                {isCellChoiceForSpecial('bottomTitle', billJson) && <FormItem
                    label="自定义底部栏"
                    key="bottomTitle"
                >
                    {getFieldDecorator('bottomTitle', {
                        initialValue: getCellValueForSpecial('bottomTitle', billJson) || '',
                    })(<TextArea allowClear placeholder="限500个字符" maxLength={500} rows={3} onBlur={handleBottomTitle} />)}
                </FormItem>}
                {isCellChoiceForSpecial('bottomPic', billJson) && <FormItem
                    label="上传图片"
                    key="bottomPic"
                >
                    {getFieldDecorator('bottomPic', {
                        initialValue: '',
                    })(<ImgCrop grid beforeCrop={handleBeforeCrop}>
                        <Upload
                            action="/choice-saas-base/paper/uploadImage"
                            listType="picture-card"
                            data={{
                                imageType: 'bottomPic',
                            }}
                            fileList={fileListBottomPic}
                            onChange={handleChangeImage}
                            onPreview={handlePreviewImage}
                            customRequest={customRequest}
                            headers={{
                                Accept: '*/*',
                                Authorization: `Bearer ${getSession('accessToken')}`,
                            }}
                        >
                            {fileListBottomPic.length < 1 && '+ Upload'}
                        </Upload>
                    </ImgCrop>)}
                    <Alert message="图片上传尺寸150*150，否则图片无法正常打印！" banner />
                </FormItem>}
            </Form>
        </div>
    );
};

export default Form.create<ContentConfigProps>()(ContentConfig);
